﻿using MultiDAQ_Analysis.Util;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

namespace MultiDAQ_Analysis.test
{
    /// <summary>
    /// 单个波形数据
    /// </summary>
    public class WaveformData
    {
        public double[] TimePoints;      // 时间点数组（ns），从0开始
        public double[] Voltages;        // 电压值数组（V）
        public int ChannelNumber;        // 通道号
        public int WaveformIndex;        // 波形序号
        public long TimestampTicks;      // 波形起始时间戳

        public WaveformData(int capacity = 1000)
        {
            TimePoints = new double[capacity];
            Voltages = new double[capacity];
        }
    }

    /// <summary>
    /// α时间谱数据解析器（支持多通道帧解析，仅解析选中通道）
    /// </summary>
    public class AlphaTimeSpectrumParser : IDisposable
    {
        #region 常量定义
        private const double SAMPLE_RATE = 250e6;
        private const double NS_PER_SAMPLE = 4.0;
        private const int ADC_RESOLUTION = 14;
        private const int ADC_MAX_VALUE = 16384;
        private const double VOLTAGE_RANGE = 3.5;
        private const double VOLTAGE_OFFSET = -1.75;

        // 帧结构常量（总帧尾仅在最后）
        private const byte FRAME_HEADER = 0xA5;       // 通道帧头标识
        private const byte TOTAL_TAIL1 = 0x0D;        // 总帧尾第一字节（整个UDP包的结束）
        private const byte TOTAL_TAIL2 = 0x0A;        // 总帧尾第二字节
        private const int CHANNEL_OFFSET = 1;         // 通道号在帧头后的偏移量
        private const int DATA_START_OFFSET = 2;      // 数据区起始偏移量（帧头+通道号之后）
        #endregion

        #region 字段
        private readonly ConcurrentQueue<byte[]> _dataQueue;
        private readonly ConcurrentQueue<WaveformData> _waveformQueue;
        private Thread _parseThread;
        private volatile bool _isRunning;
        private volatile bool _disposed = false;

        // 异步数据发送相关
        private CancellationTokenSource _dataCts;
        private Task _dataSendTask;

        // 多通道配置（新增通道选择）
        public Dictionary<int, double> ChannelThresholds { get; set; }  // 通道阈值
        public HashSet<int> SelectedChannels { get; set; }              // 选中的通道（仅解析这些通道）
        public int MaxWaveformPoints { get; set; } = 10000;

        // 多通道状态管理
        private enum ParseState { Idle, Triggered }
        private Dictionary<int, ParseState> _channelStates = new Dictionary<int, ParseState>();
        private Dictionary<int, List<double>> _channelWaveformTimes = new Dictionary<int, List<double>>();
        private Dictionary<int, List<double>> _channelWaveformVoltages = new Dictionary<int, List<double>>();
        private Dictionary<int, int> _channelValidCounters = new Dictionary<int, int>();
        private int _totalWaveformCounter = 0;
        private List<byte> _frameBuffer = new List<byte>();  // 总数据缓存
        #endregion

        #region 构造函数
        public AlphaTimeSpectrumParser()
        {
            _dataQueue = new ConcurrentQueue<byte[]>();
            _waveformQueue = new ConcurrentQueue<WaveformData>();

            // 初始化8通道默认配置
            ChannelThresholds = new Dictionary<int, double>();
            SelectedChannels = new HashSet<int> { 1, 2, 3 }; // 默认解析所有通道
            for (int i = 1; i <= 3; i++)
            {
                ChannelThresholds[i] = 0.5;  // 默认阈值0.5V
                _channelStates[i] = ParseState.Idle;
                _channelWaveformTimes[i] = new List<double>();
                _channelWaveformVoltages[i] = new List<double>();
                _channelValidCounters[i] = 0;
            }
        }
        #endregion

        #region 公共方法
        /// <summary>
        /// 获取指定通道的阈值
        /// </summary>
        public double GetChannelThreshold(int channel)
        {
            return ChannelThresholds.TryGetValue(channel, out double threshold) ? threshold : 0.5;
        }

        /// <summary>
        /// 设置指定通道的阈值
        /// </summary>
        public void SetChannelThreshold(int channel, double threshold)
        {
            if (channel >= 1 && channel <= 8)
            {
                ChannelThresholds[channel] = threshold;
            }
        }

        /// <summary>
        /// 设置需要解析的通道（覆盖原有选择）
        /// </summary>
        public void SetSelectedChannels(params int[] channels)
        {
            SelectedChannels.Clear();
            foreach (var ch in channels.Where(c => c >= 1 && c <= 8))
            {
                SelectedChannels.Add(ch);
            }
        }

        public void Start()
        {
            if (_isRunning) return;

            _isRunning = true;
            _totalWaveformCounter = 0;
            _frameBuffer.Clear();

            // 重置所有通道状态
            foreach (int channel in Enumerable.Range(1, 8))
            {
                _channelStates[channel] = ParseState.Idle;
            }

            // 启动解析线程
            _parseThread = new Thread(ParseLoop)
            {
                IsBackground = true,
                Name = "AlphaMultiChannelParser",
                Priority = ThreadPriority.Normal
            };
            _parseThread.Start();

            // 启动异步数据发送任务
            _dataCts = new CancellationTokenSource();
            _dataSendTask = SendDataAsync(_dataCts.Token);

            Console.WriteLine($"[多通道α解析器] 已启动 - 解析通道: {string.Join(",", SelectedChannels)}");
        }

        public void Stop()
        {
            if (!_isRunning) return;

            // 停止异步数据发送
            if (_dataCts != null)
            {
                _dataCts.Cancel();
                _dataCts.Dispose();
                _dataCts = null;
            }
            if (_dataSendTask != null)
            {
                _dataSendTask.Wait(1000);
                _dataSendTask = null;
            }

            // 停止解析线程
            _isRunning = false;
            _parseThread?.Join(2000);

            Console.WriteLine($"[多通道α解析器] 已停止");
        }

        public void EnqueueData(byte[] data, int length)
        {
            if (data == null || length <= 0 || !_isRunning) return;
            byte[] dataCopy = new byte[length];
            Array.Copy(data, 0, dataCopy, 0, length);
            _dataQueue.Enqueue(dataCopy);
        }

        public bool TryGetWaveform(out WaveformData waveform)
        {
            return _waveformQueue.TryDequeue(out waveform);
        }

        public List<WaveformData> GetAllWaveforms()
        {
            var waveforms = new List<WaveformData>();
            while (TryGetWaveform(out var waveform))
            {
                waveforms.Add(waveform);
            }
            return waveforms;
        }
        #endregion

        #region 解析核心
        private void ParseLoop()
        {
            while (_isRunning)
            {
                if (_dataQueue.TryDequeue(out byte[] data))
                {
                    try
                    {
                        ParseDataPacket(data);
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine($"[解析错误] {ex.Message}");
                    }
                }
                else
                {
                    Thread.Sleep(1);
                }
            }
        }

        /// <summary>
        /// 解析完整的UDP包（包含8个通道数据+总帧尾0D 0A）
        /// </summary>
        private void ParseDataPacket(byte[] data)
        {
            if (data == null || data.Length == 0) return;

            // 累加数据到缓存
            _frameBuffer.AddRange(data);

            // 查找总帧尾（0D 0A），确定完整包的范围
            int totalTailIndex = FindTotalTailIndex(_frameBuffer);
            if (totalTailIndex == -1)
            {
                // 未找到完整帧尾，保留缓存（可能跨包）
                return;
            }

            // 提取有效数据（从第一个A5到总帧尾之前）
            int firstHeaderIndex = _frameBuffer.IndexOf(FRAME_HEADER);
            if (firstHeaderIndex == -1 || firstHeaderIndex >= totalTailIndex)
            {
                // 无有效帧头，清空缓存
                _frameBuffer.Clear();
                return;
            }

            // 有效数据：从第一个A5到总帧尾前（不含帧尾）
            byte[] validData = new byte[totalTailIndex - firstHeaderIndex];
            Array.Copy(_frameBuffer.ToArray(), firstHeaderIndex, validData, 0, validData.Length);

            // 移除已解析的部分（包含总帧尾）
            _frameBuffer.RemoveRange(0, totalTailIndex + 2);

            // 分割并解析有效数据中的8个通道
            ParseAllChannels(validData);
        }

        /// <summary>
        /// 查找总帧尾（0D 0A）的起始索引
        /// </summary>
        private int FindTotalTailIndex(List<byte> buffer)
        {
            for (int i = 0; i < buffer.Count - 1; i++)
            {
                if (buffer[i] == TOTAL_TAIL1 && buffer[i + 1] == TOTAL_TAIL2)
                {
                    return i; // 返回0D的索引
                }
            }
            return -1;
        }

        /// <summary>
        /// 分割并解析有效数据中的所有通道（按A5 XX分割）
        /// </summary>
        private void ParseAllChannels(byte[] validData)
        {
            List<int> headerIndices = new List<int>();

            // 找到所有通道帧头（A5）的索引
            for (int i = 0; i < validData.Length; i++)
            {
                if (validData[i] == FRAME_HEADER)
                {
                    headerIndices.Add(i);
                }
            }

            // 按帧头分割每个通道的数据（最多8个通道）
            for (int i = 0; i < headerIndices.Count && i < 8; i++)
            {
                int currentHeaderIndex = headerIndices[i];
                // 确定当前通道数据的结束索引（下一个帧头或数据末尾）
                int nextHeaderIndex = (i + 1 < headerIndices.Count) ? headerIndices[i + 1] : validData.Length;

                // 提取通道帧（包含A5和通道号）
                if (currentHeaderIndex + 1 >= nextHeaderIndex)
                {
                    continue; // 无效帧（至少需要A5+通道号）
                }

                int channel = validData[currentHeaderIndex + CHANNEL_OFFSET]; // 提取通道号
                if (channel < 1 || channel > 8)
                {
                    continue; // 无效通道
                }

                // 仅解析选中的通道
                if (!SelectedChannels.Contains(channel))
                {
                    continue;
                }

                // 提取当前通道的数据区（A5+通道号之后，到下一个帧头之前）
                int dataLength = nextHeaderIndex - currentHeaderIndex - DATA_START_OFFSET;
                if (dataLength <= 0)
                {
                    continue; // 无有效数据
                }

                byte[] dataPayload = new byte[dataLength];
                Array.Copy(validData, currentHeaderIndex + DATA_START_OFFSET, dataPayload, 0, dataLength);

                // 解析该通道的数据
                ParseChannelData(channel, dataPayload);
            }
        }

        /// <summary>
        /// 解析指定通道的数据载荷
        /// </summary>
        private void ParseChannelData(int channel, byte[] dataPayload)
        {
            if (dataPayload.Length < 2) return;

            int sampleCount = dataPayload.Length / 2;  // 每个采样点2字节
            double threshold = GetChannelThreshold(channel);

            for (int i = 0; i < sampleCount; i++)
            {
                int byteIndex = i * 2;
                if (byteIndex + 1 >= dataPayload.Length) break;

                // 解析ADC值（大端模式）
                ushort adcValue = (ushort)((dataPayload[byteIndex] << 8) | dataPayload[byteIndex + 1]);
                double voltage = ConvertADCToVoltage(adcValue);

                // 处理单个采样点
                ProcessChannelSample(channel, voltage, threshold);
            }
        }

        /// <summary>
        /// 处理通道的单个采样点
        /// </summary>
        private void ProcessChannelSample(int channel, double voltage, double threshold)
        {
            ParseState currentState = _channelStates[channel];
            List<double> timePoints = _channelWaveformTimes[channel];
            List<double> voltages = _channelWaveformVoltages[channel];
            int validCounter = _channelValidCounters[channel];

            switch (currentState)
            {
                case ParseState.Idle:
                    if (voltage > threshold)
                    {
                        // 触发波形采集
                        _channelStates[channel] = ParseState.Triggered;
                        timePoints.Clear();
                        voltages.Clear();
                        validCounter = 1;

                        timePoints.Add(0);
                        voltages.Add(voltage);
                    }
                    break;

                case ParseState.Triggered:
                    if (voltage > threshold)
                    {
                        // 继续采集（未达最大点数）
                        if (timePoints.Count < MaxWaveformPoints)
                        {
                            double relativeTime = validCounter * NS_PER_SAMPLE;
                            timePoints.Add(relativeTime);
                            voltages.Add(voltage);
                            validCounter++;
                        }
                    }
                    else
                    {
                        // 低于阈值，结束当前波形
                        if (timePoints.Count > 0)
                        {
                            SaveChannelWaveform(channel, timePoints, voltages);
                        }
                        _channelStates[channel] = ParseState.Idle;
                        validCounter = 0;
                    }
                    break;
            }

            // 保存状态
            _channelValidCounters[channel] = validCounter;
        }

        /// <summary>
        /// 保存通道的完整波形
        /// </summary>
        private void SaveChannelWaveform(int channel, List<double> timePoints, List<double> voltages)
        {
            var waveform = new WaveformData(timePoints.Count)
            {
                TimePoints = timePoints.ToArray(),
                Voltages = voltages.ToArray(),
                ChannelNumber = channel,
                WaveformIndex = _totalWaveformCounter++,
                TimestampTicks = DateTime.UtcNow.Ticks
            };

            _waveformQueue.Enqueue(waveform);

            if (AppConfig.LogPrint == 1)
            {
                Console.WriteLine($"[通道{channel} 波形{waveform.WaveformIndex}] " +
                                 $"点数:{waveform.TimePoints.Length}, " +
                                 $"时长:{waveform.TimePoints.Last():F2}ns, " +
                                 $"峰值:{waveform.Voltages.Max():F3}V");
            }
        }

        /// <summary>
        /// ADC值转换为电压
        /// </summary>
        private double ConvertADCToVoltage(ushort adcValue)
        {
            return adcValue * VOLTAGE_RANGE / ADC_MAX_VALUE + VOLTAGE_OFFSET;
        }
        #endregion

        #region 异步数据发送
        /// <summary>
        /// 异步循环发送模拟数据
        /// </summary>
        private async Task SendDataAsync(CancellationToken cancellationToken)
        {
            while (!cancellationToken.IsCancellationRequested)
            {
                try
                {
                    OnUdpDataReceived(); // 模拟UDP数据接收
                    await Task.Delay(1000, cancellationToken); // 1ms间隔
                }
                catch (OperationCanceledException)
                {
                    Console.WriteLine("异步数据发送已停止");
                    break;
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"数据发送失败: {ex.Message}");
                    await Task.Delay(10, cancellationToken);
                }
            }
        }

        ///// <summary>
        ///// 模拟UDP数据接收（包含8个通道+总帧尾）
        ///// </summary>
        //public void OnUdpDataReceived()
        //{
        //    var testFrames = new List<string>
        //    {
        //        "A5 01 32 49 00 00 00 05 32 49 37 D9 3B 70 37 D9 32 49",  // 通道1（无单独帧尾）
        //        "A5 02 32 49 00 00 00 05 32 49 37 D9 3B 70 37 D9 32 49",  // 通道2
        //        "A5 03 32 49 00 00 00 05 32 49 37 D9 3B 70 37 D9 32 49",  // 通道3
        //        "A5 04 32 49 00 00 00 00 ",  // 通道4
        //        "A5 05 32 49 00 00 00 00 ",  // 通道5
        //        "A5 06 32 49 00 00 00 00 ",  // 通道6
        //        "A5 07 32 49 00 00 00 00 ",  // 通道7
        //        "A5 08 32 49 00 00 00 00 ",  // 通道8
        //        "0D 0A"                                                  // 总帧尾
        //    };

        //    byte[] mixedData = CombineHexFrames(testFrames);
        //    EnqueueData(mixedData, mixedData.Length);
        //}

        /// <summary>
        /// 模拟UDP数据接收（生成多个"1V→1.75V→1V"的随机波形）
        /// </summary>
        /// <summary>
        /// 模拟UDP数据接收（每个通道1000个点，每100点一个0.99V→峰值→0.99V的波形）
        /// </summary>
        /// <summary>
        /// 模拟UDP数据接收（每个通道1000个点，每100点一个0.99V→峰值→0.99V的波形，兼容低版本.NET）
        /// </summary>
        /// <summary>
        /// 模拟UDP数据接收（每个通道1000个点，每100点一个0.99V→随机峰值(1.5-1.75V)→0.99V的波形）
        /// </summary>
        public void OnUdpDataReceived()
        {
            var dataBytes = new List<byte>();
            // 0.99V对应的ADC值（基于转换公式计算：(0.99 + 1.75) * 16384 / 3.5 ≈ 12744）
            const int baseAdcFor0_99V = 12744;
            // 1.5V对应的ADC值（(1.5 + 1.75) * 16384 / 3.5 ≈ 15109）
            const int minPeakAdc = 15109;
            // 1.75V对应的ADC值（(1.75 + 1.75) * 16384 / 3.5 = 16384）
            const int maxPeakAdc = 16384;

            const int pointsPerWave = 100;      // 每个波形的点数
            const int totalWaves = 10;          // 总波形数（10*100=1000点/通道）
            var random = new Random();          // 用于生成随机峰值

            // 仅为选中的通道生成数据
            foreach (int channel in SelectedChannels.OrderBy(c => c))
            {
                if (channel < 1 || channel > 8) continue;

                // 添加通道帧头（A5 + 通道号）
                dataBytes.Add(FRAME_HEADER); // A5
                dataBytes.Add((byte)channel);

                // 生成1000个点（10个完整波形）
                for (int wave = 0; wave < totalWaves; wave++)
                {
                    // 为当前波形随机生成一个峰值（1.5V~1.75V对应的ADC值）
                    int currentPeakAdc = random.Next(minPeakAdc, maxPeakAdc + 1);

                    // 每个波形：前50点上升，后50点下降
                    for (int i = 0; i < pointsPerWave; i++)
                    {
                        ushort adcValue;
                        if (i < pointsPerWave / 2)
                        {
                            // 上升阶段（0-49点）：0.99V → 当前峰值
                            double ratio = (double)i / (pointsPerWave / 2 - 1); // 0→1
                            adcValue = (ushort)Math.Round(baseAdcFor0_99V + ratio * (currentPeakAdc - baseAdcFor0_99V));
                        }
                        else
                        {
                            // 下降阶段（50-99点）：当前峰值 → 0.99V
                            double ratio = (double)(i - pointsPerWave / 2) / (pointsPerWave / 2 - 1); // 0→1
                            adcValue = (ushort)Math.Round(currentPeakAdc - ratio * (currentPeakAdc - baseAdcFor0_99V));
                        }

                        // 手动边界检查（替代Math.Clamp）
                        if (adcValue < baseAdcFor0_99V)
                            adcValue = (ushort)baseAdcFor0_99V;
                        else if (adcValue > maxPeakAdc)
                            adcValue = (ushort)maxPeakAdc;

                        // 大端模式写入
                        dataBytes.Add((byte)(adcValue >> 8));
                        dataBytes.Add((byte)(adcValue & 0xFF));
                    }
                }
            }

            // 添加总帧尾（0D 0A）
            dataBytes.Add(TOTAL_TAIL1); // 0D
            dataBytes.Add(TOTAL_TAIL2); // 0A

            // 入队数据
            EnqueueData(dataBytes.ToArray(), dataBytes.Count);
        }
        #endregion

        #region 资源释放
        public void Dispose()
        {
            if (_disposed) return;
            Stop();
            while (_dataQueue.TryDequeue(out _)) { }
            while (_waveformQueue.TryDequeue(out _)) { }
            _frameBuffer.Clear();
            _disposed = true;
            Console.WriteLine("[多通道α解析器] 资源已释放");
        }
        #endregion
    }

    //// 测试示例
    //public class Program
    //{
    //    public static void Main(string[] args)
    //    {
    //        using (var parser = new AlphaTimeSpectrumParser())
    //        {
    //            // 仅解析通道1、3、5
    //            parser.SetSelectedChannels(1, 3, 5);
    //            // 设置通道阈值
    //            parser.SetChannelThreshold(1, 0.6);
    //            parser.SetChannelThreshold(3, 0.5);

    //            parser.Start();
    //            Console.WriteLine("解析器启动，将运行5秒...");
    //            Thread.Sleep(5000); // 运行5秒

    //            // 获取解析结果
    //            var waveforms = parser.GetAllWaveforms();
    //            Console.WriteLine($"\n5秒内共解析到 {waveforms.Count} 个波形");
    //            foreach (var wf in waveforms)
    //            {
    //                Console.WriteLine($"通道{wf.ChannelNumber} - 波形{wf.WaveformIndex}：{wf.Voltages.Length}个点");
    //            }

    //            parser.Stop();
    //        }
    //    }
    //}
}